package benchmark

import (
	"encoding/json"
	"fmt"
	"log"
	"os/exec"
	"time"
)

type Runner struct {
	Image string
}

func NewRunner(image string) *Runner {
	return &Runner{Image: image}
}

func (r *Runner) RunNormal() (*Metrics, error) {
	log.Printf("[benchmark] starting normal container: %s", r.Image)
	start := time.Now()
	if err := exec.Command("ctr", "run", "--rm", "--net-host", r.Image, "test-normal").Run(); err != nil {
		return nil, err
	}
	end := time.Now()
	return &Metrics{
		Image:           r.Image,
		Mode:            "normal",
		StartTime:       start,
		EndTime:         end,
		StartupDuration: end.Sub(start),
	}, nil
}

func (r *Runner) RunOnyx() (*Metrics, error) {
	log.Printf("[benchmark] starting onyx container: %s", r.Image)
	start := time.Now()
	if err := exec.Command("ctr", "run", "--rm", "--net-host", r.Image, "test-onyx").Run(); err != nil {
		return nil, err
	}
	end := time.Now()

	stats, _ := FetchDaemonStats()

	return &Metrics{
		Image:            r.Image,
		Mode:             "onyx",
		StartTime:        start,
		EndTime:          end,
		StartupDuration:  end.Sub(start),
		CacheHit:         stats.CacheHit,
		CacheMiss:        stats.CacheMiss,
		BlocksDownloaded: stats.Downloaded,
		CacheSizeBytes:   stats.CacheSize,
	}, nil
}

func (r *Runner) RunCompare() {
	m1, err1 := r.RunNormal()
	if err1 != nil {
		log.Fatalf("normal run failed: %v", err1)
	}

	m2, err2 := r.RunOnyx()
	if err2 != nil {
		log.Fatalf("onyx run failed: %v", err2)
	}

	rep := CompareResults(m1, m2)
	data, _ := json.MarshalIndent(rep, "", "  ")
	fmt.Println(string(data))
}
